home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
System Booster
/
System Booster.iso
/
Archives
/
Timing
/
shelltimer.lzh
/
ShellTimer.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-04
|
9KB
|
406 lines
;/* Execute me to Compile and link ShellTimer.c
;shelltimer start verbose
; For debugging, use the following command:
;lc -. -b1 -cfistq -j73 -v -Lit -d3 -isrc:memlib -dMWDEBUG=1 ShellTimer.c
; For production, use the following command:
lc -. -O -ms -b1 -cfistq -j73 -Lit -tr ShellTimer.c
;echo "Time to compile and link: " NOLINE
;shelltimer stop
quit
*/
/***
**** SHELLTIMER.C
****
**** Creation: John Lindwall
**** 19 Jan 1992
****
**** Description: Client program for ShellTimer system. The user
**** invokes timer commands via this program. The commands are
**** passed to the ShellTimerDaemon for processing. The client
**** displays the results of the command, if any.
****
**** As written, this program requires AmigaDOS 2.04. It could
**** be modified to run under 1.3, but I don't have the inclination.
**** 2.0 features used include local shell environment variables,
**** ReadArgs(), and System().
****
**** This program must be run from the shell. ShellTimer exits
**** gracefully if AmigaDOS 2.0 is not in charge, or if not run
**** from the shell.
****
**** See ShellTimer.doc for more information.
****
**** The ShellTimer System (which includes the programs
**** ShellTimerDaemon and ShellTimer) is released into the Public
**** Domain by the author, John Lindwall. I ask that the archive
**** be kept intact with the docs and the source code. Bug reports
**** should be sent to me at johnl@crash.cts.com.
****
**** Note: The code is not commented ... sorry.
****
**** Overhauls:
***/
#include <exec/ports.h>
#include <dos/dos.h>
#include <dos/var.h>
#include <dos/rdargs.h>
#include <dos/dostags.h>
#include <devices/timer.h>
#include <utility/tagitem.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "ShellTimer.h"
/* Command line parsing stuff */
#define ARGTEMPLATE "START/S,STOP/S,CANCEL/S,QUIT/S,HELP/S,V=VERBOSE/S,Q=QUERY/S"
#define OPT_START 0
#define OPT_STOP 1
#define OPT_CANCEL 2
#define OPT_QUIT 3
#define OPT_HELP 4
#define OPT_VERBOSE 5
#define OPT_QUERY 6
#define OPT_COUNT 7
#define SECONDS_PER_MINUTE 60
#define SECONDS_PER_HOUR 3600
#define SECONDS_PER_DAY (SECONDS_PER_HOUR * 24)
#define APPNAME "ShellTimer"
#define ADOS2_VERSION 37
int ParseCommandLine(void);
BOOL SendCommand(int command);
void PrintResults(int command);
void PrintElapsedTime(struct timeval *diffTime);
void Print(char *s);
void ShowHelp(void);
struct ST_Message message;
static int verbose = FALSE;
UBYTE versionTag[] = "\0$VER: " APPNAME " 1.0 (03.02.92)";
void
main(int argc, char *argv[])
{
int command;
extern struct DOSLibrary *DOSBase;
if( argc == 0 ) /* Bail out if started from WorkBench */
{
exit(-10);
}
if( DOSBase->dl_lib.lib_Version < ADOS2_VERSION )
{
Print(APPNAME " Requires AmigaDOS 2.0!\n");
exit(-20);
}
#ifdef MWDEBUG
MWInit(NULL, 0, "CON:0/200/639/199/MemLib");
#endif
command = ParseCommandLine();
if( command != ST_ERR )
{
if( command != ST_HELP )
{
if( SendCommand(command) )
{
PrintResults(command);
}
}
else
{
ShowHelp();
}
}
else
{
Print("Invalid parameters\n");
}
#ifdef MWDEBUG
MWTerm();
#endif
exit(0);
}
int
ParseCommandLine()
{
ULONG result[OPT_COUNT];
struct RDArgs *rda;
memset(result, '\0', sizeof(result));
if( (rda = ReadArgs(ARGTEMPLATE, result, NULL)) != NULL )
{
FreeArgs(rda);
if( result[OPT_VERBOSE] )
{
verbose = TRUE;
}
if( result[OPT_START] )
{
return(ST_START);
}
if( result[OPT_STOP] )
{
return(ST_STOP);
}
if( result[OPT_CANCEL] )
{
return(ST_CANCEL);
}
if( result[OPT_QUIT] )
{
return(ST_QUIT);
}
if( result[OPT_HELP] )
{
return(ST_HELP);
}
if( result[OPT_QUERY] )
{
return(ST_QUERY);
}
return(ST_TOGGLE); /* Default action if no args supplied */
}
return(ST_ERR);
}
BOOL
SendCommand(int command)
{
struct LocalVar *shellPID;
struct MsgPort *publicPort, *myPort;
BPTR file;
int systemStat, i;
static struct TagItem daemonTags[] =
{
SYS_Input, 0,
SYS_Output, NULL,
SYS_Asynch, TRUE,
SYS_UserShell, TRUE,
TAG_DONE
};
shellPID = FindVar("process", GVF_LOCAL_ONLY);
if( shellPID == NULL )
{
Print("Can't get shell PID!\n");
#ifndef DEBUG
exit(-1);
#endif
}
#ifdef DEBUG
message.requestID = 999;
#else
message.requestID = atoi(shellPID->lv_Value);
#endif
message.code = command;
message.msg.mn_Length = sizeof(struct ST_Message);;
Forbid();
if( (publicPort = FindPort(ST_PORT)) == NULL )
{
Permit();
if( command == ST_QUIT )
{
return(FALSE);
}
file = Open("NIL:", MODE_OLDFILE);
daemonTags[0].ti_Data = file;
systemStat = SystemTagList("ShellTimerDaemon", daemonTags);
if( systemStat == 0 )
{
if( verbose )
{
Print("Timer daemon loaded.\n");
}
}
else
{
Print("Unable to load ShellTimerDaemon!\n");
return(FALSE);
}
/* Give the daemon a little while to start up */
for( i = 0; i < 4; i++ )
{
Delay(25);
if( FindPort(ST_PORT) != NULL )
{
break;
}
}
Forbid();
}
if( (publicPort = FindPort(ST_PORT)) == NULL )
{
Permit();
Print("Can't locate timer daemon.\n");
return(FALSE);
}
else
{
if( (myPort = CreateMsgPort()) != NULL )
{
message.msg.mn_ReplyPort = myPort;
PutMsg(publicPort,&message);
Permit();
WaitPort(myPort);
DeletePort(myPort);
return(TRUE);
}
}
}
void
PrintResults(int command)
{
if( message.code != ST_ERR )
{
switch( message.code )
{
case ST_START:
if( verbose )
{
Print("Timer started\n");
}
break;
case ST_STOP:
if( verbose )
{
Print("Timer stopped - Elapsed Time: ");
}
PrintElapsedTime(&(message.diffTime));
break;
case ST_CANCEL:
if( verbose )
{
Print("Timer cancelled\n");
}
break;
case ST_QUERY:
if( verbose )
{
Print("Timer Query - Current elapsed time: ");
}
PrintElapsedTime(&(message.diffTime));
break;
case ST_ERR_NO_PENDING:
if( verbose )
{
Print("No pending timer request\n");
}
break;
case ST_TIMEWARP:
if( verbose )
{
Print("Let's do the TimeWarp again!\n");
}
Print("Error: System clock faulty or reset\n");
break;
case ST_QUIT:
Print("ShellTimerDaemon unloaded\n");
break;
}
}
else
{
Print("ShellTimerDaemon returned an error\n");
}
}
void
PrintElapsedTime(struct timeval *diffTime)
{
ULONG timedSeconds, days, hours, minutes, seconds;
char string[80];
timedSeconds = diffTime->tv_secs;
days = hours = minutes = seconds = 0;
if( timedSeconds >= SECONDS_PER_DAY )
{
days = timedSeconds / SECONDS_PER_DAY;
timedSeconds %= SECONDS_PER_DAY;
}
if( timedSeconds >= SECONDS_PER_HOUR )
{
hours = timedSeconds / SECONDS_PER_HOUR;
timedSeconds %= SECONDS_PER_HOUR;
}
if( timedSeconds >= SECONDS_PER_MINUTE )
{
minutes = timedSeconds / SECONDS_PER_MINUTE;
timedSeconds %= SECONDS_PER_MINUTE;
}
seconds = timedSeconds;
timedSeconds = diffTime->tv_secs;
if( verbose )
{
if( days > 0 )
{
sprintf(string, "%ld Day%s, ", days, days == 1 ? NULL : "s");
Print(string);
}
if( timedSeconds >= SECONDS_PER_HOUR )
{
sprintf(string, "%ld Hour%s, ", hours, hours == 1 ? NULL : "s");
Print(string);
}
if( timedSeconds >= SECONDS_PER_MINUTE )
{
sprintf(string, "%ld Minute%s, ", minutes, minutes == 1 ? NULL : "s");
Print(string);
}
sprintf(string, "%ld Second%s\n", seconds, seconds == 1 ? NULL : "s");
Print(string);
}
else
{
if( days > 0 )
{
sprintf(string, "%ld ", hours);
Print(string);
}
sprintf(string, "%02ld:%02ld:%02ld\n", hours, minutes, seconds);
Print(string);
}
}
void
Print(char *string)
{
Write(Output(), string, strlen(string));
}
void
ShowHelp(void)
{
Print("\n");
Print(&versionTag[7]);
Print(" - A shell-based stopwatch by John Lindwall");
Print("\n\n" APPNAME " " ARGTEMPLATE);
Print("\n\n START - Starts the timer STOP - Stops timer & prints time");
Print( "\n CANCEL - Abort the timer session QUIT - Kill daemon and quit");
Print( "\n HELP - Show help message VERBOSE - Use wordy messages");
Print( "\n QUERY - Show current timer value");
Print( "\n\nIf no arguments are supplied, ShellTimer toggles between performing START");
Print( "\nand STOP. So, typing 'ShellTimer' once starts the timer; typing 'ShellTimer'");
Print( "\nagain will stop the timer and display the result.\n\n");
}